package cn.zz.veggie.persistence.repository;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.springframework.stereotype.Repository;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.zz.comm.core.types.query.PageQuery;
import cn.zz.comm.exception.classes.FatalErrorException;
import cn.zz.comm.util.CollectorUtil;
import cn.zz.comm.util.NumberUtil;
import cn.zz.veggie.model.domain.Category;
import cn.zz.veggie.model.query.CategoryQuery;
import cn.zz.veggie.persistence.dao.CategoryDao;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 商品分类(Category)repo
 *
 * @author zhongq
 * @since 2024-04-27 13:30:42
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class CategoryRepository {

	private final CategoryDao categoryDao;

	public Category findByPidAndName(Integer parentId, String name) {
		return null;
	}

	public Category findById(Integer id) {
		if (!NumberUtil.isPositive(id)) {
			return null;
		}
		final CategoryQuery query = new CategoryQuery();
		query.setId(id);
		return categoryDao.selectOne(query);
	}


	public Map<Integer, Category> findByIds(Collection<Integer> ids) {
		if (CollectionUtil.isEmpty(ids)) {
			return Collections.emptyMap();
		}
		final CategoryQuery query = new CategoryQuery();
		query.setIds(ids);
		query.page(PageQuery.size(ids.size()));
		final List<Category> records = categoryDao.select(query);
		return CollectorUtil.btmByKeyFun(records, Category::getId);
	}

	public List<Category> findByPage(CategoryQuery query, PageQuery page) {
		page.setTotal(categoryDao.selectCount(query));
		if (page.hasMoreItems()) {
			return categoryDao.select(query);
		}
		return Collections.emptyList();
	}

	public void save(Category category) {
		Objects.requireNonNull(category);
		if (category.getId() == null) {
			// insert
			final int effect = categoryDao.insert(category);
			if (effect != 1) {
				throw new FatalErrorException("created category fail ");
			}
			log.info("created category for {}", category.getId());
		} else {
			// update
			final int effect = categoryDao.updateById(category);
			if (effect != 1) {
				throw new FatalErrorException("update category fail ");
			}
			log.info("updated category for {}", category.getId());
		}
	}

	public void removeById(Integer id) {
		Objects.requireNonNull(id);
		final int effect = categoryDao.deleteById(id);
		if (effect != 1) {
			log.error("delete");
			throw new FatalErrorException("delete category fail ");
		}
		log.info("delete category for {}", id);
	}

	public void removeByIds(Collection<Integer> ids) {
		if (CollUtil.isEmpty(ids)) {
			return;
		}
		final int effect = categoryDao.deleteByIds(ids);
		log.info("delete category for {}", effect);
	}

	public List<Category> findAll() {
		final CategoryQuery query = new CategoryQuery();
		query.page(PageQuery.all());
		return categoryDao.select(query);
	}

	public Category findOneByParentId(Integer parentId) {
		Objects.requireNonNull(parentId);
		final CategoryQuery query = new CategoryQuery();
		query.setPid(parentId);
		return categoryDao.selectOne(query);
	}

	public List<Category> findAllByPid(Integer parentId) {
		Objects.requireNonNull(parentId);
		final CategoryQuery query = new CategoryQuery();
		query.setPid(parentId);
		return findByQuery(query);
	}

	public List<Category> findByQuery(CategoryQuery query) {
		query.page(PageQuery.all());
		return categoryDao.select(query);
	}
}